#include "modbus.h"
#include "stdio.h"
#include "systick.h"
#include "usart_device.h"
#include "ms35711.h"
#include "user_device.h"

/* IWDG init function */
void MX_IWDG_Init(void)
{
   /* confiure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
    fwdgt_config(1000, FWDGT_PSC_DIV8);

    /* After 0.2 seconds to generate a reset */
    fwdgt_enable();
}

// 读取异常状态
uchar Read_Exception()
{
    return program_status;
}

void Enter_Boot_Loader(void)
{
    MX_IWDG_Init();
}
void Restart(void)
{
    NVIC_SystemReset();
}
// 诊断
void Diagnose()
{
    ushort subfun = from_little_endian_16(*(ushort*)&uart0_buf[2]);    // 子功能代码
    switch(subfun)
    {
                case 0x00:      // 原样返回请求数据
                case 0x03:      // 改变ASCII结束符
                        uart0_len -= 2;
                        Response();
                        break;
    
                case 0x01:      // 复位通讯端口
                        uart0_len = 6;
                        subfun = *(ushort*)&uart0_buf[4];
                        Response();
    
                        // 等等发送结束
                        while(uart0_tx_pending);
                        if (subfun == 0xFF00)   // 清除记录事件
                                event_count = 0;
    
                        // 等等停止位发送结束
                        Delay_us(60000);
                        // 重启
                        if (subfun == 0xFFFF)
                            Enter_Boot_Loader();
                                
                        else
                            Restart();
    
                        break;          // 运行不到此处
    
                case 0x02:      // 返回诊断寄存器
                        uart0_len = 6;
                        *(ushort*)&uart0_buf[4] = diagnostic;
                        Response();
                        break;
    
                case 0x04:      // 强迫进入“只听”模式
                        ps_listen_only = 1;
                        No_Response();
                        Log_Event(EVENT_ENTER_LISTEN_ONLY);
                        break;
    
                case 0x0A:      // 清除计数器和诊断寄存器
                        diagnostic                  = 0;        // 诊断寄存器
                        bus_message_count           = 0;        // 总线上消息数量
                        bus_error_count             = 0;        // 总线上通讯错误数量
                        bus_exception_count         = 0;        // 总线上异常应答数量
                        server_message_count        = 0;        // 下位机消息数量
                        server_no_response_count    = 0;        // 下位机未响应消息数量
                        server_exception_count      = 0;        // 下位机异常应答消息数量
                        server_busy_count           = 0;        // 下位机状态忙数量
                        bus_char_overrun_count      = 0;        // 总线字符过载（Overrun）数量
    
                        uart0_len -= 2;
                        Response();
                        break;
    
                case 0x0B:      // 返回总线上消息数量
                        uart0_len = 6;
                        *(ushort*)&uart0_buf[4] = bus_message_count;
                        Response();
                        break;
    
                case 0x0C:      // 返回总线上通讯错误数量
                        uart0_len = 6;
                        *(ushort*)&uart0_buf[4] = bus_error_count;
                        Response();
                        break;
    
                case 0x0D:      // 返回总线上异常应答数量
                        uart0_len = 6;
                        *(ushort*)&uart0_buf[4] = bus_exception_count;
                        Response();
                        break;
    
                case 0x0E:      // 返回下位机消息数量
                        uart0_len = 6;
                        *(ushort*)&uart0_buf[4] = server_message_count;
                        Response();
                        break;
    
                case 0x0F:      // 返回下位机未响应消息数量
                        uart0_len = 6;
                        *(ushort*)&uart0_buf[4] = server_no_response_count;
                        Response();
                        break;
    
                case 0x10:      // 返回下位机异常应答消息数量
                        uart0_len = 6;
                        *(ushort*)&uart0_buf[4] = server_exception_count;
                        Response();
                        break;
    
                case 0x11:      // 返回下位机状态忙数量
                        uart0_len = 6;
                        *(ushort*)&uart0_buf[4] = server_busy_count;
                        Response();
                        break;
    
                case 0x12:      // 返回总线字符过载（Overrun）数量
                        uart0_len = 6;
                        *(ushort*)&uart0_buf[4] = bus_char_overrun_count;
                        Response();
                        break;
    
                case 0x14:      // 清除过载（Overrun）计数器和标志
                        uart0_len -= 2;
                        bus_char_overrun_count = 0;
                        Response();
                        break;
    
                default:        // 未实现或不正确的子功能代码
                        Exception_Response(ILLEGAL_FUNCTION);
                        break;
    }
}


void Log_Event(uchar event)
{
    event_log[++event_count & MAX_EVENT_MASK] = event;
    if (event_count > MAX_EVENT_MASK)
        event_count = (event_count & MAX_EVENT_MASK) | MAX_EVENT_COUNT;
}

